include( 'shared.lua' )
include( 'tables.lua' )
include( 'admin.lua' )
include( 'cl_spawnmenu.lua' )
include( 'cl_postprocess.lua' )
include( 'cl_scoreboard.lua' )
include( 'cl_hudpickup.lua' )
include( 'cl_deathnotice.lua' )

function GM:Initialize( )	
	self.BaseClass:Initialize()
	GAMEMODE:SetupTeams()
	ply = LocalPlayer()
	ply:ConCommand("mat_monitorgamma 2.2")
	
	WindVector = Vector(math.random(-15,15),math.random(-15,15),0) //fake wind velocity 4 da clientside effects
	
	RedScore, BlueScore = 0,0
	Mayday = false
	IsInVehicle = false
	CurVehicle = nil
	ToggleMusic = true
	VehicleBuild = false
	VehicleHealth = 0
	MaxVehicleHealth = 10
	Class = "Soldier"
	BuildStage = 1
	PreviewPart = nil
	PreviewTime =  0
	ViewOffset = 30
	CurVehicleOffset = Angle(0,0,0)
	ShowHelpTime = CurTime()
	
	AimerX, AimerY = 0,0
	
	surface.CreateFont("Tahoma", 14, 500, true, false, "HudText")
	surface.CreateFont("Tahoma", 12, 500, true, false, "HudTextSmall")
	surface.CreateFont("Tahoma", 16, 500, true, false, "HelpText")
	surface.CreateFont("Tahoma", 22, 500, true, false, "BuildText")

end

function GM:Think()
	local fire = LocalPlayer():GetNetworkedBool("onfire")
	if fire and LocalPlayer():Alive() then
		
		ColorModify[ "$pp_colour_addr" ]		= .25
		ColorModify[ "$pp_colour_mulr" ] 		= .33
		ColorModify[ "$pp_colour_addg" ]		= .14
		local hpratio = LocalPlayer():Health() / MaxPlayerHealth
		MotionBlur = .9 * (1-hpratio)
	
		local Velocity 	= Vector( 0, 0, 1 )
		local emitter = ParticleEmitter( LocalPlayer():GetPos() )
		local pos = LocalPlayer():GetPos() + LocalPlayer():OBBMaxs() * math.Rand(0,1) + LocalPlayer():OBBMins() * math.Rand(0,1)
		
		for i=1, math.Rand(1,3) do
			
			// If we're the local player then put the flames in front of the view more
			if ( self == LocalPlayer() ) then
				pos = pos + LocalPlayer():GetAngles():Forward() * 15
			end
		
			local particle = emitter:Add( "effects/muzzleflash"..math.random(1,4), pos )

			particle:SetVelocity( (Velocity * math.Rand( 10, 150 )) + WindVector )
			particle:SetDieTime( math.Rand( 0.2, 0.7 ) )
			particle:SetStartAlpha( math.Rand( 150, 250 ) )
			particle:SetEndAlpha( math.Rand( 0, 2 ) )
			particle:SetStartSize( math.Rand( 10, 20 ) )
			particle:SetEndSize( math.Rand( 30, 70 ) )
			particle:SetRoll( math.Rand( 0, 360 ) )
			particle:SetRollDelta( math.Rand( -0.1, 0.1 ) )
			particle:SetColor( math.Rand( 150, 255 ), math.Rand( 100, 150 ), 100 )
			particle:VelocityDecay( false )
		
		end	
			local immopos = LocalPlayer():GetPos() + Vector(math.random(-10,10),math.random(-10,10),math.random(5,75))
			local particle = emitter:Add( "effects/muzzleflash"..math.random(1,4), immopos )

			particle:SetVelocity( (Velocity * math.Rand( 10, 150 )) + WindVector )
			particle:SetDieTime( math.Rand( 0.2, 0.6 ) )
			particle:SetStartAlpha( math.Rand( 150, 250 ) )
			particle:SetEndAlpha( math.Rand( 5, 20 ) )
			particle:SetStartSize( math.Rand( 10, 20 ) )
			particle:SetEndSize( math.Rand( 50, 70 ) )
			particle:SetRoll( math.Rand( 0, 360 ) )
			particle:SetRollDelta( math.Rand( -0.1, 0.1 ) )
			particle:SetColor( math.Rand( 150, 255 ), math.Rand( 100, 150 ), 100 )
			particle:VelocityDecay( false )
			
		for i=1,math.random(1,2) do
			local particle = emitter:Add("effects/fire_embers"..math.random(1,3), pos )
			particle:SetVelocity( (Vector(math.random(-15,15),math.random(-15,15),math.random(10,50)) * Velocity) + WindVector )
			particle:SetDieTime(math.Rand(2,3))
			particle:SetStartAlpha(math.random(140,220))
			particle:SetEndAlpha(10)
			particle:SetStartSize(math.Rand(3,4))
			particle:SetEndSize(0)
			particle:SetRoll(math.random(-200,200))
			particle:SetRollDelta( math.random( -1, 1 ) )
			particle:SetColor(255, 220, 100)
			particle:SetGravity(Vector(0,0,-200)) //-600 is normal
			particle:SetCollide(true)
			particle:SetBounce(0.1) 
			
			local particle = emitter:Add( "particles/smokey", pos )

			particle:SetVelocity( (Velocity * math.Rand( 50, 150 )) + WindVector )
			particle:SetDieTime( math.Rand( 0.4, 0.5 ) )
			particle:SetStartAlpha( math.Rand( 40, 60 ) )
			particle:SetEndAlpha( math.Rand( 10, 20 ) )
			particle:SetStartSize( math.Rand( 10, 20 ) )
			particle:SetEndSize( math.Rand( 40, 80 ) )
			particle:SetRoll( math.Rand( 0, 360 ) )
			particle:SetRollDelta( math.Rand( -0.1, 0.1 ) )
			particle:SetColor( 40,40,40 )
			particle:VelocityDecay( false )
		end
		emitter:Finish()
	end
	local v = LocalPlayer():GetNetworkedEntity("burncorpse")
	if v and v:IsValid() then
		v.FlameTime = v.FlameTime or CurTime() + math.random(7,9)
		if v.FlameTime > CurTime() then
			local pos = v:GetPos() + Vector(math.Rand(-11,11),math.Rand(-11,11),0)
			local Velocity 	= Vector( 0, 0, 1 )
			local emitter = ParticleEmitter( v:GetPos() )
			
			local particle = emitter:Add( "effects/muzzleflash"..math.random(1,4), pos )
			particle:SetVelocity( (Velocity * math.Rand( 10, 120 )) + WindVector )
			particle:SetDieTime( math.Rand( 0.2, 0.4 ) )
			particle:SetStartAlpha( math.Rand( 100, 160 ) )
			particle:SetEndAlpha( math.Rand( 30, 60 ) )
			particle:SetStartSize( math.Rand( 10, 15 ) )
			particle:SetEndSize( math.Rand( 15, 25 ) )
			particle:SetRoll( math.Rand( 0, 360 ) )
			particle:SetRollDelta( math.Rand( -0.1, 0.1 ) )
			particle:SetColor( math.Rand( 150, 255 ), math.Rand( 100, 150 ), 100 )
			particle:VelocityDecay( false )
			
			local particle = emitter:Add( "particles/smokey", pos )
			particle:SetVelocity( (Velocity * math.Rand( 10, 30 )) + WindVector )
			particle:SetDieTime( math.Rand( 1, 2 ) )
			particle:SetStartAlpha( math.Rand( 20, 50 ) )
			particle:SetEndAlpha( math.Rand( 5, 10 ) )
			particle:SetStartSize( math.Rand( 5, 10 ) )
			particle:SetEndSize( math.Rand( 15, 30 ) )
			particle:SetRoll( math.Rand( 0, 360 ) )
			particle:SetRollDelta( math.Rand( -0.1, 0.1 ) )
			particle:SetColor( 40,40,40 )
			particle:VelocityDecay( false )
			
			emitter:Finish()
		end
	end
end

local WalkTimer = 0
local VelSmooth = 0
function GM:CalcView( ply, origin, angle, fov )

	CurVehicle = ply:GetNetworkedEntity("CurVehicle") or nil

	if IsInVehicle and Class == "Pilot" then
		if CurVehicle and CurVehicle:IsValid() then
		
			local paim = ply:EyeAngles() //aim angle of player
			local vaim = CurVehicle:GetTrueAngles() //aim angle of vehicle
			
			local aimvec = CurVehicle:GetPos() + (LocalPlayer():GetAimVector() * 9000) //aimvector of player
			local spos = aimvec:ToScreen()
			
			lastang = lastang or vaim
			
			local angdiff = Angle()
			angdiff.p = math.AngleDifference(lastang.p, vaim.p)
			angdiff.y = math.AngleDifference(lastang.y, vaim.y)
			angdiff.r = math.AngleDifference(lastang.r, vaim.r)
			
			lastang.p = math.ApproachAngle( lastang.p, vaim.p, angdiff.p * FrameTime() * 2 )
			lastang.y = math.ApproachAngle( lastang.y, vaim.y, angdiff.y * FrameTime() * 2 )
			lastang.r = math.ApproachAngle( lastang.r, vaim.r, angdiff.r * FrameTime() * 2 )
			
			ply:SetAngles(vaim)
			ply:SetEyeAngles(lastang - (angdiff * 1.5) + paim)
			
			//record the player's view angles every frame, as well as the vehicle's.
			//check how far the vehicle angles have modified and add it to the player's angles.
			
			if not spos.visible then
				ply:SetEyeAngles(CurVehicle:GetTrueAngles())
			else
				AimerX, AimerY = spos.x, spos.y
			end
			
			local pmin,pmax,ymin,ymax,rmin,rmax,ang
			pmin, pmax = math.NormalizeAngle(vaim.p - 90), math.NormalizeAngle(vaim.p + 90)
			ymin, ymax = math.NormalizeAngle(vaim.y - 90), math.NormalizeAngle(vaim.y + 90)
			rmin, rmax = math.NormalizeAngle(vaim.r - 90), math.NormalizeAngle(vaim.r + 90)
			
			ang = paim
			ang.p = math.Clamp( paim.p, pmin, pmax )
			ang.y = math.Clamp( paim.y, ymin, ymax )
			ang.r = vaim.r
		
			local view = {}
			view.origin = CurVehicle:GetPos() + (CurVehicle:GetTrueUp() * ViewOffset)
			view.angles = vaim --veh angles
			return view
		end
	elseif IsInVehicle and Class == "Driver" then
		if CurVehicle and CurVehicle:IsValid() then
		
			local paim = ply:EyeAngles() //aim angle of player
			local vaim = CurVehicle:GetTrueAngles() //aim angle of vehicle
		
			local view = {}
			view.origin = CurVehicle:GetPos() + (CurVehicle:GetTrueUp() * ViewOffset)
			view.angles = paim --player angles
			return view
		end
	end

	local vel = ply:GetVelocity()
	local ang = ply:EyeAngles()
	
	local corpse = ply:GetNetworkedEntity("corpse")
	if corpse then
		if corpse:IsValid() and (ply:Alive() == false) then
			local view = {}
			view.origin = corpse:GetPos() + Vector(0,0,70)
			view.angles = ang
			return view
		end
	end
	
	if ( ply:GetGroundEntity() != NULL ) then	
		angle.roll = angle.roll + math.sin( WalkTimer ) * VelSmooth * 0.001
		angle.pitch = angle.pitch + math.sin( WalkTimer * 0.31 ) * VelSmooth * 0.001
	end
	
	VelSmooth = VelSmooth * 0.55 + vel:Length() * 0.05
	WalkTimer = WalkTimer + VelSmooth * FrameTime() * 0.055
	
	angle.roll = angle.roll + ang:Right():DotProduct( vel ) * 0.005
		
	return self.BaseClass:CalcView( ply, origin, angle, fov )
end

function UpdateRedScore( msg )
	local num = msg:ReadShort()
	RedScore = num
end
usermessage.Hook("UpdateRedScore",UpdateRedScore) 

function UpdateBlueScore( msg )
	local num = msg:ReadShort()
	BlueScore = num
end
usermessage.Hook("UpdateBlueScore",UpdateBlueScore) 

function SetCurVehicleOffset( msg )
	local num = msg:ReadAngle()
	CurVehicleOffset = num
end
usermessage.Hook("CurVehicleOffset",SetCurVehicleOffset) 

function SetOffset( msg )
	local num = msg:ReadShort()
	ViewOffset = num
	LocalPlayer():EmitSound(Sound("weapons/pistol/pistol_reload1.wav"),100,100)
end
usermessage.Hook("ViewOffset",SetOffset) 

function IsMayday( msg )
	local num = msg:ReadShort()
	if num == 5 then
		Mayday = true
	else
		Mayday = false
	end
end
usermessage.Hook("IsMayday",IsMayday)

function InVehicle( msg )
	local num = msg:ReadShort()
	if num == 5 then
		IsInVehicle = true
	else
		IsInVehicle = false
	end
end
usermessage.Hook("IsInVehicle",InVehicle) 

function GetVehicleHealth( msg )
	VehicleHealth = msg:ReadShort()
end
usermessage.Hook("VehicleHealth",GetVehicleHealth) 

function GetMaxVehicleHealth( msg )
	MaxVehicleHealth = msg:ReadShort()
end
usermessage.Hook("MaxVehicleHealth",GetMaxVehicleHealth) 

function GM:PostProcessPermitted( name )
	return false
end

function GM:PlayerBindPress( ply, bind, pressed )
	if not pressed then return false end
	
	if bind == "toggle_zoom" then
		return true --disable zoot suit
	end
end

function DrawVisEffects()
	if Mayday then
		ColorModify[ "$pp_colour_addr" ]		= .1
		ColorModify[ "$pp_colour_mulr" ] 		= .3
	end
end
hook.Add("HUDPaint", "DrawPlayersVisuals", DrawVisEffects)

function GetTeamColor()
return team.GetColor(ply:Team()) end

function DrawHUD()

	if !LocalPlayer():Alive() then return end
	
	//font colors
	color_red = Color(220, 40, 40, 245)
	color_blue = Color(40, 40, 220, 245)
	color_lightred = Color(210, 130, 130, 255)
	color_lightblue = Color(130, 130, 210, 255)
	color_white = Color(255,255,255,255)
	color_green = Color(50,255,50,255)

	local ply = LocalPlayer()
	local hp = ply:Health() or 1
	
	RedBeacon = ply:GetNetworkedInt("beaconhealth1")
	BlueBeacon = ply:GetNetworkedInt("beaconhealth2")
	BeaconMax = GameInfo.BeaconHealth
	
	local ammo
	local maxammo
	
	if not IsInVehicle then
		if (ply:GetActiveWeapon() == NULL) then 
			ammo = 1 
		elseif ply:GetActiveWeapon():IsValid() and ply:GetActiveWeapon() ~= NULL then
			ammo = ply:GetActiveWeapon():Clip1() or 1 
		end
		
		if (ply:GetActiveWeapon() == NULL) then
			maxammo = 1 
		elseif ply:GetActiveWeapon():IsValid() and ply:GetActiveWeapon() != NULL then
			maxammo = ply:GetActiveWeapon():GetMaxAmmo() or 1		
		end
	end
	
	local seconds = (ply:GetNetworkedFloat("timeleft") - CurTime())
	local border = 0
	local w = ScrW()
	local h = ScrH()
	
	if not vgui.CursorVisible() then
		draw.RoundedBox(8, w*.01-0.8, h*.01-0.8, w*.10+2, h*.06-4, Color(200, 200, 200, 175))
		draw.RoundedBox(8, w*.01, h*.01, w*.10, h*.05+2, Color(50, 50, 50, 155))
		draw.DrawText("Red Barons: "..RedScore.."", "DefaultSmall", w*.06, h*.02, color_lightred,1,1)
		draw.DrawText("Blue Bombers: "..BlueScore.."", "DefaultSmall", w*.06, h*.04, color_lightblue,1,1)
		
		draw.RoundedBox(0, w*.01, h*.075, w*.10, h*.025, Color(40, 40, 40, 160))//top
		draw.RoundedBox(0, w*.01, h*.11, w*.10, h*.025, Color(40, 40, 40, 160))//bottom
		draw.RoundedBox(0, w*.01, h*.075, math.min(((w*.10)/ BeaconMax)*BlueBeacon,(w*.10)), h*.025, color_blue)//top
		draw.RoundedBox(0, w*.01, h*.11, math.min(((w*.10)/ BeaconMax)*RedBeacon,(w*.10)), h*.025, color_red)//bottom
		draw.DrawText("Beacon Health: "..math.Round(math.Clamp((BlueBeacon/BeaconMax)*100,0,100)).."%", "HudTextSmall", w*.06, h*.08, color_white,1,1)
		draw.DrawText("Beacon Health: "..math.Round(math.Clamp((RedBeacon/BeaconMax)*100,0,100)).."%", "HudTextSmall", w*.06, h*.115, color_white,1,1)
	end
	
	if (IsInVehicle == false) then
		if not vgui.CursorVisible() then
	
			ClassTbl = {}
			for i=1,#ClassTypes do
				if string.lower(ClassTypes[i].Name) == string.lower(Class) then
					ClassTbl = ClassTypes[i]
				end
			end
		
			MaxPlayerHealth = ClassTbl.Health or 100
		
			local hpratio = hp/MaxPlayerHealth
			local hpred=255*(1-hpratio)
			local hpgreen=200*hpratio
			local hpblue =30*hpratio

			local c_hp=Color(hpred,hpgreen,hpblue,200) 
		
			draw.RoundedBox( border, w*.01, h*.79, w*.04, h*.20, Color(60,60,60,120) )
			draw.RoundedBox( border, w*.01, h*.79, w*.04, math.min(((h*.20)/ ClassTbl.Health)*hp,(h*.20)), c_hp )
			draw.SimpleText("Health", "HudTextSmall", w*.03, h*.80, color_white,1,1)
			
			local maxammo2 = ply:GetNetworkedFloat("maxclip") or 1
			
			local hpratio = ammo/maxammo
			local hpred=255*(1-hpratio)
			local hpgreen=50
			local hpblue =200*hpratio
			local c_am=Color(hpred,hpgreen,hpblue,200) 
			
			draw.RoundedBox( border, w*.06, h*.79, w*.04, h*.20, Color(60,60,60,120) )
			draw.RoundedBox( border, w*.06, h*.79, w*.04, ((h*.20)/ maxammo) * ammo, c_am )
			draw.SimpleText("Ammo", "HudTextSmall", w*.08, h*.80, color_white,1,1)
		elseif VehicleBuild == true then
			draw.RoundedBox( border, 0, 0, w, h*.12, Color(20,20,20,170) )
			draw.RoundedBox( border, 0, h*.85, w, h*.20, Color(20,20,20,170) )
			draw.SimpleText("Vehicle Buildinator X1200", "BuildText", w*.5, h*.14, GetTeamColor(),1,1)
		end
	else
		local hpratio = VehicleHealth/MaxVehicleHealth
		local hpred=255*(1-hpratio)
		local hpgreen=200*hpratio
		local hpblue =30*hpratio

		local c_hp=Color(hpred,hpgreen,hpblue,200) 
	
		draw.RoundedBox( border, w*.01, h*.79, w*.04, h*.20, Color(60,60,60,120) )
		draw.RoundedBox( border, w*.01, h*.79, w*.04, math.min(((h*.20)/ MaxVehicleHealth)*VehicleHealth,(h*.20)), c_hp )
		draw.SimpleText("Armor", "HudTextSmall", w*.03, h*.80, color_white,1,1)
		
		local vmax = ply:GetNetworkedFloat("maxvehicleammo")
		local vammo = ply:GetNetworkedFloat("vehicleammo")
		
		if vammo == 0 then		
			local reloadbase = ply:GetNetworkedFloat("basetime")
			local reloadtime = ply:GetNetworkedFloat("reloadtime")
			local hpratio = TimeScale(reloadtime-reloadbase,reloadtime)
			local hpred=255*(1-hpratio)
			local hpgreen=50
			local hpblue =200*hpratio
			local c_am=Color(hpred,hpgreen,hpblue,200) 
		
			draw.RoundedBox( border, w*.06, h*.79, w*.04, h*.20, Color(60,60,60,120) )
			draw.RoundedBox( border, w*.06, h*.79, w*.04, math.min((h*.20)*(TimeScale(reloadtime-reloadbase,reloadtime))), c_am )
			draw.SimpleText("Ammo", "HudTextSmall", w*.08, h*.80, color_white,1,1)
		else
			local hpratio = vammo/vmax
			local hpred=255*(1-hpratio)
			local hpgreen=50
			local hpblue =200*hpratio
			local c_am=Color(hpred,hpgreen,hpblue,200) 
		
			draw.RoundedBox( border, w*.06, h*.79, w*.04, h*.20, Color(60,60,60,120) )
			draw.RoundedBox( border, w*.06, h*.79, w*.04, ((h*.20)/ vmax) * vammo, c_am )
			draw.SimpleText("Ammo", "HudTextSmall", w*.08, h*.80, color_white,1,1)
		end
		
		if IsInVehicle and Class == "Pilot" then
		
			surface.SetDrawColor( 180, 15, 15, 255 )
			surface.DrawLine( AimerX - 18, AimerY, AimerX + 18, AimerY )
			surface.DrawLine( AimerX, AimerY - 10, AimerX, AimerY + 10 )
			surface.DrawLine( AimerX-30, AimerY - 16, AimerX-30, AimerY + 16 )
			surface.DrawLine( AimerX+30, AimerY - 16, AimerX+30, AimerY + 16 )
			
			//draw.DrawText("[  +  ]", "HudText", AimerX, AimerY, Color(200,20,20,255),1,1)
		
			surface.SetTexture(surface.GetTextureID("sprites/reticle"))
			surface.SetDrawColor(255, 255, 255, 255)
			surface.DrawTexturedRect(w*.11, h*.79, w*.155, h*.20) //The altimeter
			
			local x1 = w*.188 //PRECISION
			local y1 = h*.89
			
			surface.SetDrawColor(255,255,255,255)
			if CurVehicle:IsValid() then
				DrawLineAngled({x=x1,y=y1},math.NormalizeAngle(180 - CurVehicle:GetTrueAngles().r),60)
				DrawLineAngled({x=x1,y=y1},math.NormalizeAngle(180 - (CurVehicle:GetTrueAngles().r + 90)),22)
			end
		end
		//altimiter, vehicle hp, etc ... driving shit
	end
end
hook.Add("HUDPaint", "DrawPlayersHUD", DrawHUD)

function TimeScale(cur,maxtime)
	if CurTime() > maxtime then return 1 end
	return math.min((CurTime() - cur) / (maxtime - cur),maxtime)
end

function DrawLineAngled( origin, ang, radius )
  local x1, x2, y1, y2, r, cos1, sin1

  r = math.rad( ang )

  cos1 = math.cos( r ) * radius
  sin1 = math.sin( r ) * radius

  x1 = origin.x - cos1
  x2 = origin.x + cos1

  y1 = origin.y - sin1
  y2 = origin.y + sin1

  surface.DrawLine( x1, y1, x2, y2 )
end

function HealthBonus(msg)
	ColorModify[ "$pp_colour_addr" ]		= .4
	ColorModify[ "$pp_colour_addg" ]		= .9
	ColorModify[ "$pp_colour_addb" ]		= .7
	ColorModify[ "$pp_colour_mulg" ] 		= .8
	ColorModify[ "$pp_colour_mulb" ] 		= .5
end
usermessage.Hook("DrawHealthBonus", HealthBonus) 

function HelpTimer( msg )
	local num = msg:ReadShort()
	ShowHelpTime = CurTime() + 10
end
usermessage.Hook("ShowHelp", HelpTimer)

function ShowHelp()
	if ShowHelpTime < CurTime() then return end
	local w = ScrW()
	local h = ScrH()
	local xp = .40
	local yp = .42
	local av = .10
	
	//The main help box
	draw.RoundedBox(8, w*.20-0.8, h*.30-0.8, w*.60+2, h*.16+10, Color(200, 200, 200, 155))
	draw.RoundedBox(8, w*.20, h*.30, w*.60, h*.16+8, Color(70, 70, 70, 155))
	
	for k,text in pairs(HelpText) do
		draw.SimpleText(text, "HelpText", w*(xp + .10), h*(yp - av), c_help,1,1)
		av = av - .02
	end
end
hook.Add("HUDPaint", "DrawPlayersHelp", ShowHelp)

function ScoreTimer( msg )
	local num = msg:ReadShort()
	ShowScore = true
	NoTables = true
end
usermessage.Hook("ShowScores", ScoreTimer) 

function ShowScores()
	if not ShowScore then return end
	if NoTables then
		MostKills = {}
		HighScore = {}
		MostDeaths = {}
		for k,v in pairs(player.GetAll()) do
			table.insert(MostKills,v:Frags().." : "..string.Left(v:Name(),14))
			table.insert(HighScore,v:GetNetworkedFloat("score").." : "..string.Left(v:Name(),14))
			table.insert(MostDeaths,v:Deaths().." : "..string.Left(v:Name(),14))
		end
		NoTables = false
		//table.sort(MostKills, function(a, b) return a > b end)
		//table.sort(MostDeaths, function(a, b) return a > b end)
		//table.sort(HighScore, function(a, b) return a > b end)
		table.sort(MostKills, function(a, b) return tonumber(string.Explode(" ",a)[1]) > tonumber(string.Explode(" ",b)[1]) end)
		table.sort(MostDeaths, function(a, b) return tonumber(string.Explode(" ",a)[1]) > tonumber(string.Explode(" ",b)[1]) end)
		table.sort(HighScore, function(a, b) return tonumber(string.Explode(" ",a)[1]) > tonumber(string.Explode(" ",b)[1]) end)
		surface.CreateFont("Tahoma", 15, 500, true, false, "ScText")
		surface.CreateFont("Tahoma", 15, 500, true, false, "ScTopText")
		surface.CreateFont("Typenoksidi", 16, 500, true, false, "ComText")
		surface.CreateFont("csd", 26, 400, true, false, "Medal")
		c_win = Color(65,115,255,255)
		c_lose = Color(255,100,50,255)
		c_kill = Color(100,255,50,255)
		SC_FixedName = string.Explode(" ",HighScore[1]) 
		KC_FixedName = string.Explode(" ",MostKills[1]) 
		DC_FixedName = string.Explode(" ",MostDeaths[1]) 
		for i=1,2 do
			SC_FixedName[i] = ""
			KC_FixedName[i] = ""
			DC_FixedName[i] = ""
		end
		SC_FixedName = string.Left(string.Trim(string.Implode(" ",SC_FixedName)),14)
		KC_FixedName = string.Left(string.Trim(string.Implode(" ",KC_FixedName)),14)
		DC_FixedName = string.Left(string.Trim(string.Implode(" ",DC_FixedName)),14)
		WinComment = ChooseString(WinnerComments)
		KillComment = ChooseString(KillerComments)
		LoseComment = ChooseString(LoserComments)
		WinComment = string.Replace(WinComment,"ply",SC_FixedName)
		KillComment = string.Replace(KillComment,"ply",KC_FixedName)
		LoseComment = string.Replace(LoseComment,"ply",DC_FixedName)
	end
	
	local w = ScrW()
	local h = ScrH()
	
	//The comment box
	draw.RoundedBox(8, w*.30-0.8, h*.30-0.8, w*.40+2, h*.07+10, Color(200, 200, 200, 155))
	draw.RoundedBox(8, w*.30, h*.30, w*.40, h*.07+8, Color(70, 70, 70, 155))
	
	//The main score box
	draw.RoundedBox(8, w*.30-0.8, h*.40-0.8, w*.40+2, h*.15+10, Color(200, 200, 200, 155))
	draw.RoundedBox(8, w*.30, h*.40, w*.40, h*.15+8, Color(70, 70, 70, 155))
	local xp = .40
	local yp = .42
	local o_red = 255
	local o_green = 255
	local o_blue = 255
	local c_grad = Color(o_red,o_green,o_blue,255)
	
	//Comments
	draw.SimpleText(WinComment..".", "ComText", w*(xp + .10), h*(yp - .10), c_win,1,1)
	draw.SimpleText(KillComment..".", "ComText", w*(xp + .10), h*(yp - .08), c_kill,1,1)
	draw.SimpleText(LoseComment..".", "ComText", w*(xp + .10), h*(yp - .06), c_lose,1,1)
	
	//Medal Logos - left side
	draw.SimpleText("g", "Medal", w*(xp - .114), h*(yp - .09), c_win,1,1)
	draw.SimpleText("D", "Medal", w*(xp - .114), h*(yp - .07), c_kill,1,1)
	draw.SimpleText("C", "Medal", w*(xp - .114), h*(yp - .05), c_lose,1,1)
	
	//Medal Logos - right side
	draw.SimpleText("g", "Medal", w*(xp + .31), h*(yp - .09), c_win,1,1)
	draw.SimpleText("D", "Medal", w*(xp + .31), h*(yp - .07), c_kill,1,1)
	draw.SimpleText("C", "Medal", w*(xp + .31), h*(yp - .05), c_lose,1,1)
	
	//Label scores
	draw.SimpleText("Highest Scores", "ScTopText", w*xp, h*yp, c_grad,1,1)
	draw.SimpleText("Most Kills", "ScTopText", w*(xp + .10), h*yp, c_grad,1,1)
	draw.SimpleText("Most Deaths", "ScTopText", w*(xp + .20), h*yp, c_grad,1,1)
	yp = yp + .02
	
	for i=1,5 do
		o_red = i*51  //255 divided by 5 is 51 ... GASP!
		o_green = (6 - i)*51  //inverse of the red value.
		o_blue = (6 - i)*51  // ditto
		c_grad = Color(o_red,o_green,o_blue,255)
		
		draw.SimpleText(HighScore[i] or "0 - Nobody", "ScText", w*xp, h*yp, c_grad,1,1)
		draw.SimpleText(MostKills[i] or "0 - Nobody", "ScText", w*(xp + .10), h*yp, c_grad,1,1)
		draw.SimpleText(MostDeaths[i] or "0 - Nobody", "ScText", w*(xp + .20), h*yp, c_grad,1,1)
		yp = yp + .02
	end
end
hook.Add("HUDPaint", "DrawPlayersScore", ShowScores)

function UpdateTime( msg )
local readval = msg:ReadShort()
	if (readval != nil) then
		GameInfo.STime = readval
	end
end
usermessage.Hook("UpdateTime", UpdateTime) 

function PlaySong( msg )
	local num = msg:ReadShort()
	if num == 5 and ToggleMusic then
		local song = ChooseRandom(WinSongs)
		//LocalPlayer():ConCommand("stopsounds")
		LocalPlayer():EmitSound(song,100,100)
	elseif num == 6 and ToggleMusic then
		local song = ChooseRandom(LoseSongs)
		//LocalPlayer():ConCommand("stopsounds")
		LocalPlayer():EmitSound(song,100,100)
	end
end
usermessage.Hook("PlaySong", PlaySong) 

function TogglePlay(ply, cmd, args)
	if ToggleMusic != true then 
		Msg("Music toggled on.\n") 
		ToggleMusic = true
	else 
		ToggleMusic = false 
		Msg("Music toggled off.\n")
	end
end
concommand.Add("pf_togglemusic",TogglePlay)

function EnableHelpMenu( msg )
local readval = msg:ReadShort()
	if (readval == 5) then
		HelpTime = CurTime() + 8
	end
end
usermessage.Hook("HelpMenu", EnableHelpMenu) 

function DrawHelp()

if HelpTime == nil or HelpTime < CurTime() then return end
	
end
hook.Add("HUDPaint", "DrawHelpHook", DrawHelp)

function HelpMenu( msg )
local readval = msg:ReadShort()
	if (readval == 5) then
		//HelpVguiMenu()
	end
end
usermessage.Hook("HelpMenu", HelpMenu) 

function PreviewVehiclePart(part)
	PreviewPart = part
	if PreviewProp and PreviewProp:IsValid() then PreviewProp:Remove() end
	PreviewProp = ents.Create("prop_physics")
	PreviewProp:SetModel(PreviewPart.Model)
	PreviewProp:SetPos(LocalPlayer():GetPos() + Vector(0,0,900))
	PreviewTime = CurTime() + 10
	R3 = {math.Rand(1,10),math.Rand(1,10),math.Rand(1,10)}
end

function TimedSin(freq,min,max,offset)
    return math.sin(freq * math.pi * 2 * CurTime() + offset) * (max-min) * 0.5 + min
end 

function FindPartInfo(part)
	local ret
	if part.Health then
		ret = {part.Health,((.6 - part.Drag)*100)*2}
	end
	if ret == nil then
		ret = {0,0}
	end
	return ret
end

function VehiclePreview()
	if PreviewPart then
		if PreviewTime > CurTime() and PreviewProp and PreviewProp:IsValid() then
			util.PrecacheModel(PreviewPart.Model)
			PreviewProp:SetModel(PreviewPart.Model)
			PreviewProp:SetPos(LocalPlayer():GetPos() + (LocalPlayer():GetForward() * 120) + (LocalPlayer():GetRight() * 35) + Vector(0,0,65))
			PreviewProp:SetAngles(Angle(math.Clamp(TimedSin(0.1,0,360,R3[1]),0,360),math.Clamp(TimedSin(0.1,0,360,R3[2]),0,360),math.Clamp(TimedSin(0.1,0,360,R3[3]),0,360)))
			local phys = PreviewProp:GetPhysicsObject()
			if phys and phys:IsValid() then
				phys:EnableGravity(false)
			end
			local vinfo = FindPartInfo(PreviewPart)
			if vinfo[1] != 0 then
				draw.SimpleText("Health: "..vinfo[1].."HP    Speed: "..vinfo[2].."%", "HelpText", ScrW()*.5, ScrH()*.16, Color(0,0,0,255),1,1)
			end
		else
			if PreviewProp and PreviewProp:IsValid() then
				PreviewProp:Remove()
			end
		end
	end
end
hook.Add("HUDPaint", "VehiclePreviewThink", VehiclePreview)

function OpenNextWindow()
	BuildStage = BuildStage + 1
	WindowOpen = true
end

function VehicleMenu( msg )
local readval = msg:ReadShort()
	if (readval == 5) then
		WindowOpen = true
		VehicleBuild = true
		gui.EnableScreenClicker(true)
	end
end
usermessage.Hook("VehicleMenu", VehicleMenu) 

function VehicleThink()
	if VehicleBuild then
		local ply = LocalPlayer()
		if BuildStage == 1 and WindowOpen then
			WindowOpen = false
			if Class == "Pilot" then
				local tbl = BuildVguiMenu(Vehicles.Aircrafts.Torsos)
				for k,v in pairs(tbl) do
					tbl[k].button.DoClick = function() LocalPlayer().Torso = Vehicles.Aircrafts.Torsos[k] OpenNextWindow() tbl[1].frame:Remove() end
					tbl[k].button.OnCursorEntered = function() PreviewVehiclePart(Vehicles.Aircrafts.Torsos[k]) end
					//OnMouseLeave?
				end
			elseif Class == "Driver" then
				local tbl = BuildVguiMenu(Vehicles.Land.Torsos)
				for k,v in pairs(tbl) do
					tbl[k].button.DoClick = function() LocalPlayer().Torso2 = Vehicles.Land.Torsos[k] OpenNextWindow() tbl[1].frame:Remove() end
					tbl[k].button.OnCursorEntered = function() PreviewVehiclePart(Vehicles.Land.Torsos[k]) end
					//OnMouseLeave?
				end
			end
		elseif BuildStage == 2 and WindowOpen then
			WindowOpen = false
			if Class == "Pilot" then
				local tbl = BuildVguiMenu(Vehicles.Aircrafts.Wings)
				for k,v in pairs(tbl) do
					tbl[k].button.DoClick = function() LocalPlayer().Wings = Vehicles.Aircrafts.Wings[k] OpenNextWindow() tbl[1].frame:Remove() end
					tbl[k].button.OnCursorEntered = function() PreviewVehiclePart(Vehicles.Aircrafts.Wings[k]) end
					//OnMouseLeave?
				end
			elseif Class == "Driver" then
				local tbl = BuildVguiMenu(Vehicles.Land.Wheels)
				for k,v in pairs(tbl) do
					tbl[k].button.DoClick = function() LocalPlayer().Wheels = Vehicles.Land.Wheels[k] OpenNextWindow() tbl[1].frame:Remove() end
					tbl[k].button.OnCursorEntered = function() PreviewVehiclePart(Vehicles.Land.Wheels[k]) end
					//OnMouseLeave?
				end
			end
		elseif BuildStage == 3 and WindowOpen then
			WindowOpen = false
			BuildStage = 1
			if Class == "Pilot" then
				local tbl = BuildVguiMenu(Vehicles.Aircrafts.Weapons)
				for k,v in pairs(tbl) do
					tbl[k].button.DoClick = function() LocalPlayer().Weapon = Vehicles.Aircrafts.Weapons[k] VehicleCommand({ply.Torso,ply.Wings,ply.Weapon}) tbl[1].frame:Remove() end
					tbl[k].button.OnCursorEntered = function() PreviewVehiclePart(Vehicles.Aircrafts.Weapons[k]) end
					//OnMouseLeave?
				end
			elseif Class == "Driver" then
				local tbl = BuildVguiMenu(Vehicles.Land.Weapons)
				for k,v in pairs(tbl) do
					tbl[k].button.DoClick = function() LocalPlayer().Weapon2 = Vehicles.Land.Weapons[k] VehicleCommand({ply.Torso2,ply.Wheels,ply.Weapon2}) tbl[1].frame:Remove() end
					tbl[k].button.OnCursorEntered = function() PreviewVehiclePart(Vehicles.Land.Weapons[k]) end
					//OnMouseLeave?
				end
			end
		end
	end
end
hook.Add("HUDPaint", "VehicleThink", VehicleThink)

function VehicleCommand( tbl )
	PreviewTime = CurTime()
	gui.EnableScreenClicker(false)
	if Class == "Driver" then
		LocalPlayer():ConCommand("landvehicle_upd_torso "..tbl[1].Name)
		LocalPlayer():ConCommand("landvehicle_upd_wheels "..tbl[2].Name)
		LocalPlayer():ConCommand("landvehicle_upd_weapon "..tbl[3].Name)
	elseif Class == "Pilot" then
		LocalPlayer():ConCommand("airvehicle_upd_torso "..tbl[1].Name)
		LocalPlayer():ConCommand("airvehicle_upd_wings "..tbl[2].Name)
		LocalPlayer():ConCommand("airvehicle_upd_weapon "..tbl[3].Name)
	end
	VehicleBuild = false
end

//This should be the basic vgui structure to make our life easier
function BuildVguiMenu(tbl)
	
	if tbl == nil then gui.EnableScreenClicker(false) return end
	local returntable = {}

	local frame = vgui.Create("DFrame")
	frame:SetSize(4,6) //obsolete
	frame:SetPos((ScrW()/10),ScrH()/2-300) //left hand side frame
	frame:PostMessage("setTitle", "text", "Selection Menu")
	frame:SetTitle("Selection Menu")
	frame.Close = function( ) LocalPlayer():ConCommand("name DO NOT CLICK THE X") end

	local xpos = 13//ScrW()/2-180
	local ypos = 30//ScrH()/2-270
	local ytotal = 50 //Was 60 before

	for k, v in pairs(tbl) do
		
		returntable[k] = {}
		returntable[k].frame = frame
		local button = vgui.Create("DButton",frame)
		button:SetText(tbl[k].Name)
		button:SetPos(xpos,ypos)
		button:SetSize(80,30)
		button.OnMouseEntered = function() gui.EnableScreenClicker(true) end
		button.DoClick = function() frame:Remove() gui.EnableScreenClicker(false) end
		returntable[k].button = button
			
		ypos = ypos + 30
		ytotal = ytotal + 30
			
	end
	frame:SetSize(105,ytotal) //set frame size!
	return returntable
end

function ClassUpdate( msg )
local readval = msg:ReadString()
	Class = readval
end
usermessage.Hook("ClassUpdate", ClassUpdate) 

function ClassCommand( arg )
	LocalPlayer():ConCommand("changeclass "..arg)
end

function ClassMenu( msg )
local readval = msg:ReadShort()
	if (readval == 5) then
		ClassVguiMenu()
	end
end
usermessage.Hook("ClassMenu", ClassMenu) 

function ClassVguiMenu()

	local classtable = ClassTypes
	gui.EnableScreenClicker(true)

	local frame = vgui.Create("DFrame")
	frame:SetSize(400,600)
	frame:SetPos(ScrW()/2-200,ScrH()/2-300) --Centre the frame
	frame:PostMessage("setTitle", "text", "Selection Menu")
	//frame:SetVisible(true)
	//frame:MakePopup() 
	//frame:SetDraggable(false)
	frame:SetTitle("Selection Menu")
	frame.Close = function( ) LocalPlayer():ConCommand("name DO NOT CLICK THE X") end
	//frame:SetZPos(1)
	local xpos = 20//ScrW()/2-180
	local ypos = 30//ScrH()/2-270
	local ytotal = 45 --Was 60 before

	for k, v in pairs(classtable) do
	
		local button = vgui.Create("DButton",frame)
		//button:SetParent(frame)
		button:SetText(classtable[k].Name)
		button:SetPos(xpos,ypos)
		//button:SetVisible(true)
		//button:MakePopup()
		//button:SetZPos(6)
		button.DoClick = function( ) ClassCommand(classtable[k].Name) frame:Remove() gui.EnableScreenClicker(false) end;
		
		local label = vgui.Create("DLabel",frame)
		label:SetText(classtable[k].Desc)
		label:SetPos(xpos+70,ypos)
		label:SetSize(300,30)
		//label:SetParent(frame)
		//label:SetVisible(true)
		//label:MakePopup()
		//label:SetZPos(6)
		
		ypos = ypos + 30
		ytotal = ytotal + 30
		
	end
	frame:SetSize(400,ytotal)
	//frame:SizeToContents()
end

function NoHud(name)
	for k, v in pairs{"CHudHealth", "CHudBattery", "CHudAmmo", "CHudSecondaryAmmo"} do
		if name == v then return false end
  	end 
end
hook.Add("HUDShouldDraw", "NoDrawHud", NoHud)

function ChooseRandom(tablename)
	local tnum = table.Count(tablename)
	local rand = math.random(1,tnum)
	util.PrecacheSound(tablename[rand])
return tablename[rand] end